#include <iostream>
#include <string>
#include <cstring>
#include <memory>
#include <ctime>

// #include <netinet/in.h>
// #include <arpa/inet.h>
// #include <unistd.h>

#include "Sock.hpp"
#include "protocol.hpp"
#include "InetAddr.hpp" // #include "Log.hpp"
// #include "LockGuard.hpp"

using namespace socket_ns;
using namespace protocol_ns;

void Usage(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

// ./tcpclient serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    InetAddr serveraddr(serverip, serverport);
    Factory factory;
    std::unique_ptr<Socket> cli = std::make_unique<TcpSocket>();
    bool res = cli->BulidClientSocket(serveraddr);
    std::string inbuffer;
    while (res)
    {
        // 1、构建一个请求
        auto req = factory.BuildRequest();

        // 2、对请求进行序列化
        std::string send_str;
        req->Serialize(&send_str);

        std::cout << "Serialize:\n" << send_str << std::endl;

        // 3、添加长度报头
        send_str = Encode(send_str);
        std::cout << "Encode:\n" << send_str << std::endl;

        // 4、
        cli->Send(send_str);

        // 5、读取答应
        int n = cli->Recv(&inbuffer);
        if (n <= 0)
            break;
        std::string package = Decode(inbuffer);
        if(package.empty())
            continue;
        // 6、反序列化
        auto resp = factory.BuildResponse();

        // 6.1 反序列化
        resp->Deserialize(package);

        // 7、 拿到了结构化的应答
        std::cout << resp->_result << "[" << resp->_code << "]" << std::endl;
    }

    return 0;
}
